<template>
  <div class="content">
    <el-upload
      :http-request="uploadFile"
      :before-remove="beforeRemove"
      :on-remove="handleRemove"
      :on-exceed="handleExceed"
      :drag="listType!=='picture'"
      :accept="accept"
      :limit="limit===1?2:limit"
      :file-list="fileList"
      :list-type="listType"
      action=""
    >

      <el-button v-if="listType==='picture'" size="small" type="primary">点击上传</el-button>

      <i v-if="listType!=='picture'" class="el-icon-upload" />
      <div v-if="listType!=='picture'" class="el-upload__text">
        将文件拖到此处，或
        <em>点击上传</em>
      </div>
      <div v-if="tips" slot="tip" class="el-upload__tip">{{ tips }}</div>
    </el-upload>
  </div>
</template>

<script>
import { buildDir } from '@/utils/file-utils'
import { fetchToken } from '@/api/sys/config/cos'
import COS from 'cos-js-sdk-v5'
import { compressImage } from '@/utils/upload'

export default {
  name: 'FileUploadCos',
  props: {
    value: String,
    accept: String,
    tips: String,
    listType: String,

    limit: {
      type: Number,
      default: 1
    },
    compress: {
      type: Number,
      default: 0
    }
  },
  data() {
    return {
      cos: null,
      taskId: '',
      fileList: [],
      conf: { }
    }
  },
  watch: {
    // 检测查询变化
    value: {
      handler() {
        this.fillValue()
      }
    }
  },

  mounted() {
    this.fetchConfig()
  },

  created() {
    this.fillValue()
  },
  methods: {

    // 填充数据
    fillValue() {
      this.fileList = []
      this.fileUrl = this.value
      if (this.fileUrl) {
        this.fileList = [{ name: this.fileUrl, url: this.fileUrl }]
      }
    },

    beforeUpload(file) {
      return compressImage(file, this.compress)
    },

    // 获取基础配置
    fetchConfig() {
      // 获得上传令牌
      fetchToken().then(res => {
        this.conf = res.data
        // 使用临时秘钥初始化上传对象
        this.cos = new COS({
          SecretId: res.data.tmpSecretId,
          SecretKey: res.data.tmpSecretKey,
          XCosSecurityToken: res.data.sessionToken
        })
      }).catch(err => {
        this.$message.error(`获取COS上传令牌失败： ${err} `)
      })
    },

    // 文件超出个数限制时的钩子
    handleExceed() {
      // 替换
      if (this.limit > 1) {
        this.$message.warning(`每次只能上传 ${this.limit} 个文件`)
      }
    },
    // 删除文件之前的钩子
    beforeRemove() {
      return this.$confirm(`确定移除文件吗？`)
    },
    // 文件列表移除文件时的钩子
    handleRemove() {
      this.$emit('input', '')
      this.fileList = []
      // 取消进行中的任务
      this.cos.cancelTask(this.taskId)
    },

    // 手动上传文件
    uploadFile(param) {
      const file = param.file
      const key = this.buildName(file)
      const that = this

      this.cos.sliceUploadFile({
        Bucket: that.conf.bucket,
        Region: that.conf.region,
        Key: key,
        StorageClass: 'STANDARD',
        Body: file,
        onTaskReady: function(taskId) {
          that.taskId = taskId
        },
        onProgress: function(progressData) {
          // 文件进度条
          const progress = progressData.percent
          const percent = progress * 100
          param.onProgress({ percent: percent })
        }
      }, function(err, data) {
        // 上传成功
        param.onSuccess()
        // 向外回调
        that.$emit('input', that.conf.url + data.Key)
      })
    },

    // 重命名文件
    buildName(file) {
      const temporary = file.name.lastIndexOf('.')
      const fileNameLength = file.name.length
      const fileFormat = file.name.substring(
        temporary + 1,
        fileNameLength
      )
      return buildDir() + '.' + fileFormat
    }
  }
}
</script>
